package com.foreveross.fetl.web.action.preprocess;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.common.remote.ftp.FtpConfig;
import com.common.remote.sftp.SFtpFileTransferClient;
import com.foreveross.fetl.common.HBaseTable;
import com.foreveross.fetl.common.cfg.system.ReportProperties;
import com.foreveross.fetl.common.hbase.client.HBaseHelper;
import com.foreveross.fetl.core.domain.task.SourceEntity;
import com.foreveross.fetl.util.DateUtils;
import com.foreveross.fetl.web.action.BaseAction;

@Controller("allFlightNoAction")
@Scope("prototype")
public class AllFlightNoAction extends BaseAction {

	/**
	 * 
	 */
	private static final long serialVersionUID = -3856663897806658561L;
	
	public String list(){
		return "METHOD";
	}
	
	public String downLoadAll(){
		String start = getRequest().getParameter("start");
		String end = getRequest().getParameter("end");
		File file=this.createExcel(start,end);
//		this.uploadFile(file, "hangxin/excel");
//		HttpServletResponse response=getResponse();
//		InputStream fis=null;
//			try {
//				response.reset();
//				OutputStream toClient = new BufferedOutputStream(
//						response.getOutputStream());
//				response.setContentType("application/vnd.ms-excel");
//				String filename=null;
//				if (getRequest().getHeader("User-Agent").toLowerCase()
//						.indexOf("firefox") > 0) {
//					filename = new String(file.getName().getBytes("UTF-8"), "ISO8859-1");// firefox浏览器
//				} else {
//					filename = URLEncoder.encode(file.getName(), "UTF-8");// 其他浏览器
//				}
//				response.setHeader("Content-Disposition", "attachment; filename="
//						+ filename);// 设定输出文件头
//				fis = new BufferedInputStream(new FileInputStream(
//						file.getPath()));
//				byte[] buffer = new byte[fis.available()];
//				fis.read(buffer);
//				fis.close();
//				
//				toClient.write(buffer);
//				toClient.flush();
//				toClient.close();
//				
//			} catch (Exception e) {
//				e.printStackTrace();
//			}finally{
//				if(null!=file)
//					   file.delete();
//				if(null!=fis){
//						try {
//							fis.close();
//						} catch (IOException e) {
//							// TODO Auto-generated catch block
//							e.printStackTrace();
//						}
//					}
//			}
		return null;
	}

	private File createExcel(String start, String end) {
		String  fileName="allFlightNo_0.xlsx";
		Map<String,Map<String,Infos>> map=new HashMap<String,Map<String,Infos>>();
		Calendar cStart = Calendar.getInstance();
		cStart.setTime(DateUtils.parse(start, "yyyy-MM-dd"));
		cStart.add(Calendar.DAY_OF_MONTH, -30);
		Calendar cEnd = Calendar.getInstance();
		cEnd.setTime(DateUtils.parse(end, "yyyy-MM-dd"));
		cEnd.add(Calendar.DAY_OF_MONTH, 1);
		ResultScanner rs = null;
		SourceEntity source = new SourceEntity();
		List<SourceEntity> listSource=source.findAll();
		int count=0;
		int i=1;
		while (cStart.before(cEnd)) {
			Date startTime=cStart.getTime();
			String grabDate=DateUtils.format(startTime, "yyyy-MM-dd");
			cStart.add(Calendar.DAY_OF_MONTH, 1);// 开始日期加1
			Date endTime=cStart.getTime();
			for(SourceEntity sen:listSource){
				String startRow=sen.getHbaseKey()+DateUtils.format(startTime, "yyyyMMdd")+"000";
				String stopRow=sen.getHbaseKey()+DateUtils.format(endTime, "yyyyMMdd")+"24Z";
				try {
					rs = HBaseHelper.getRecords(HBaseTable.BASE_DATA_FLIGHT,
							startRow, stopRow,new String[]{"planeinfo"},null);
					for (Result res : rs) {
						 try {
							Map<String, String> curMap = HBaseHelper
									.transformHBaseRowToMap(res).get("planeinfo");
							String flightDate=curMap.get("flightBatchDate");
							if(null==flightDate && null!=curMap.get("flightBatchStartTime"))
								flightDate=DateUtils.format(DateUtils.parse(curMap.get("flightBatchStartTime").substring(0, 12), "yyyyMMddHHmm"), "yyyy-MM-dd");
							if(flightDate.compareTo(start)<0 || flightDate.compareTo(end)>0)
								continue;
							
							Map<String,Infos> flightMap;
							if(map.containsKey(flightDate))
								flightMap=map.get(flightDate);
							else
								flightMap=new HashMap<String,Infos>();
							
							double price=Double.parseDouble(null==curMap.get("lowerPrice")?"0":curMap.get("lowerPrice"));
							if(price<=0)
								continue;
							String flightNo=curMap.get("flightId");
							
							if(null==flightNo)
								continue;
							String channel = null==curMap.get("grabChannel")?curMap.get("carrierFullName"):curMap.get("grabChannel");
							String grabTime=curMap.get("grabDate");
							if(null!=grabTime)
								grabTime=DateUtils.format(DateUtils.parse(grabTime, "yyyyMMddHHmmssSSS"), "yyyy-MM-dd HH:mm:ss");
							String line=curMap.get("fromCity")+"-"+curMap.get("toCity");
							if(flightMap.containsKey(flightNo)){
								Infos info=flightMap.get(flightNo);
								if(info.getPrice()>price){
									info.setChannel(channel);
									info.setGrabTime(grabTime);
									info.setLine(line);
									info.setPrice(price);
								}
							}else{
								Infos infos=new Infos(channel,line,grabTime,price);
								flightMap.put(flightNo, infos);
							}
							if(!map.containsKey(flightDate))
								map.put(flightDate, flightMap);
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
					
				} catch (IOException e) {
					e.printStackTrace();
				}finally{
					if(null!=rs){
						rs.close();
					}
				}
			}
			
			if(map.containsKey(grabDate)){
				count++;
				if(count>=10){
					try {
						this.uploadFile(new File(fileName), "hangxin/excel");
					} catch (Exception e) {
						e.printStackTrace();
					}
					fileName="allFlightNo_"+i+".xlsx";
					i++;
					count=0;
				}
				this.saveToExcel(fileName,grabDate,map.get(grabDate));
				map.remove(grabDate);
			}
			
		}
		return null;
	}

	private void saveToExcel(String fileName, String grabDate,
			Map<String, Infos> map) {
		File file=new File(fileName);
		XSSFWorkbook  workbook = null;
		OutputStream os = null;
		FileInputStream is =null;
		try {
			if(null==file || !file.exists()){
				workbook = new XSSFWorkbook();
			}else{
				is= new FileInputStream(file.getPath());
				workbook = new XSSFWorkbook(is);
			}
			XSSFSheet sheet = workbook.createSheet(grabDate);
			String[] title ={"航线","航班号","价格","渠道","抓取时间"};
			XSSFRow row = sheet.createRow(0);
	        for(int i=0;i<title.length;i++){
	        	XSSFCell cell = row.createCell(i);
	        	cell.setCellValue(title[i]);
	        }
	        int column=1;
	        XSSFRow   rows =null;
	        XSSFCell cell=null;
	        for(String key:map.keySet()){
	        	Infos info=map.get(key);
	        	rows = sheet.createRow(column);
				cell=rows.createCell(0);
				cell.setCellValue(info.getLine());
				
				cell=rows.createCell(1);
				cell.setCellValue(key);
				
				cell=rows.createCell(2);
				cell.setCellValue(info.getPrice());
				
				cell=rows.createCell(3);
				cell.setCellValue(info.getChannel());
				
				cell=rows.createCell(4);
				cell.setCellValue(info.getGrabTime());
				 column++;
	        }
	        if(null!=is){
	        	is.close();
	        }
	        os = new FileOutputStream(file); 
	        workbook.write(os);
	        os.close();
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			 file=null;
			if(null!=os){
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
	}
	
	private void uploadFile(File f,String remotePath) {
		String address =ReportProperties.getAddress();
		int port= Integer.parseInt(null==ReportProperties.getPort()? "22":ReportProperties.getPort());
		String userName= ReportProperties.getUserName();
		String passWord =ReportProperties.getPassword();
		String path=ReportProperties.getPath();
		if(!path.endsWith("/")) path+="/";
		path=path.replace("webdata/", "");
		//ftp连接配置
    	FtpConfig config =new FtpConfig(address,port,userName,passWord);
		SFtpFileTransferClient sftpClient=new SFtpFileTransferClient(config);
		InputStream in =null;
		boolean flag=false;
		try {
			try {
				flag = sftpClient.connect();
			} catch (Exception e) {
				e.printStackTrace();
				Thread.sleep(10 * 1000L);
				flag = sftpClient.connect();
			}
			if(null!=remotePath && remotePath.endsWith("/")){
				remotePath=remotePath.substring(0, remotePath.length()-1);
			}
			String dir=path+remotePath;
			if(flag){
				//如果目录不存在则创建
				String[] dirs=dir.split("/");
				StringBuffer buffer=new StringBuffer();
				for(String d:dirs){
					buffer.append(d+"/");
					if(!sftpClient.isDirectoryExists(buffer.toString())){
						sftpClient.makeDirectory(buffer.toString());
					}
				}
				in=new FileInputStream(f);
				
				sftpClient.upload(in, dir+"/"+f.getName());
				
				sftpClient.disconnect();
			}
		} catch (Exception e) {
			try {
				throw e;
			} catch (Exception e1) {
				e1.printStackTrace();
			}
		}finally{
			if(null!=sftpClient){
				sftpClient.disconnect();	
			}
			try {
			if (in != null) {
				in.close();
			}
		} catch (Exception e) {
		}
		}
	}
	
}

class Infos{
	private String channel;
	private String line;
	private String grabTime;
	private double price;
	
	public Infos(){
		
	}
	public Infos(String channel,String line,String grabTime,double price){
		this.channel=channel;
		this.line=line;
		this.grabTime=grabTime;
		this.price=price;
	}
	
	public String getChannel() {
		return channel;
	}
	public void setChannel(String channel) {
		this.channel = channel;
	}
	public String getGrabTime() {
		return grabTime;
	}
	public void setGrabTime(String grabTime) {
		this.grabTime = grabTime;
	}
	public double getPrice() {
		return price;
	}
	public void setPrice(double price) {
		this.price = price;
	}
	public String getLine() {
		return line;
	}
	public void setLine(String line) {
		this.line = line;
	}
	
	
}
